home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Personal Computer World 2006 May
/
PCWMAY06.iso
/
Software
/
Toolkit
/
Songbird 0.1
/
Songbird_0_1_0.exe
/
chrome
/
content
/
songbird_hack.js
< prev
next >
Wrap
Text File
|
2006-02-10
|
92KB
|
3,070 lines
/*
//
// BEGIN SONGBIRD GPL
//
// This file is part of the Songbird web player.
//
// Copyright⌐ 2006 Pioneers of the Inevitable LLC
// http://songbirdnest.com
//
// This file may be licensed under the terms of of the
// GNU General Public License Version 2 (the ôGPLö).
//
// Software distributed under the License is distributed
// on an ôAS ISö basis, WITHOUT WARRANTY OF ANY KIND, either
// express or implied. See the GPL for the specific language
// governing rights and limitations.
//
// You should have received a copy of the GPL along with this
// program. If not, go to http://www.gnu.org/licenses/gpl.html
// or write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// END SONGBIRD GPL
//
*/
//
// Yes, I know this file is a mess.
//
// Yes, I know we have to clean it up.
//
// Yes, this will happen soon.
//
// I promise. Or something.
//
// - mig
//
try
{
const LOAD_FLAGS_BYPASS_HISTORY = 64;
// okay
var thePlaylistReader = null;
// Hooray for event handlers!
function myPlaybackEvent( key, value )
{
}
// Create a player remote with an explicit event handler.
var myPlayerRemote = new CPlayerRemote( myPlaybackEvent );
// I should remember to destruct him, eventually, but he was instantiated into the global scope.
theSongbirdStrings = document.getElementById( "songbird_strings" );
var SBServiceTreeListener = {
m_CurrentSelection: "",
m_Tree: null,
QueryInterface : function(aIID) {
if (!aIID.equals(Components.interfaces.nsIXULBuilderListener) &&
!aIID.equals(Components.interfaces.nsISupportsWeakReference) &&
!aIID.equals(Components.interfaces.nsISupports))
{
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
willRebuild : function( builder )
{
try
{
// Save selection
if ( this.m_Tree && ( this.m_Tree.currentIndex != -1 ) )
{
var column = this.m_Tree.columns ? this.m_Tree.columns["frame_service_tree_label"] : "frame_service_tree_label";
this.m_CurrentSelection = this.m_Tree.view.getCellText( this.m_Tree.currentIndex, column );
}
saveCollapsedStates(this.m_Tree);
}
catch( err )
{
alert( err );
}
},
didRebuild : function( builder )
{
try
{
// Restore selection
if ( this.m_Tree && ( this.m_Tree.currentIndex == -1 ) && ( this.m_CurrentSelection.length > 0 ) )
{
var column = this.m_Tree.columns ? this.m_Tree.columns["frame_service_tree_label"] : "frame_service_tree_label";
for ( var i = 0; i < this.m_Tree.view.rowCount; i++ )
{
if ( this.m_CurrentSelection == this.m_Tree.view.getCellText( i, column ) )
{
this.m_Tree.view.selection.currentIndex = i;
this.m_Tree.view.selection.select( i );
this.m_CurrentSelection = "";
break;
}
}
}
this.m_CurrentSelection = "";
restoreCollapsedStates(this.m_Tree);
}
catch( err )
{
alert( err );
}
}
}
function saveCollapsedStates( tree )
{
try
{
var col = tree.columns ? tree.columns["frame_service_tree_label"] : "frame_service_tree_label";
for (var i=0;i<tree.view.rowCount;i++)
{
if (tree.view.isContainer(i))
{
var item_url = tree.view.getCellText( i, col );
var item_remote = new sbIDataRemote( "collapsed_" + tree.id + "_" + item_url );
item_remote.SetValue(!tree.view.isContainerOpen(i));
}
}
}
catch (err)
{
alert('songbird_hack - saveCollapsedStates - ' + err);
}
}
function restoreCollapsedStates( tree )
{
try
{
var col = tree.columns ? tree.columns["frame_service_tree_label"] : "frame_service_tree_label";
for (var i=0;i<tree.view.rowCount;i++)
{
if (tree.view.isContainer(i))
{
var item_url = tree.view.getCellText( i, col );
var item_remote = new sbIDataRemote( "collapsed_" + tree.id + "_" + item_url );
if (item_remote.GetIntValue())
{
if (tree.view.isContainerOpen(i))
{
tree.view.toggleOpenState(i);
}
}
}
}
}
catch (err)
{
alert('songbird_hack - restoreCollapsedStates - ' + err);
}
}
var SBWindowMinMaxCB =
{
// Shrink until the box doesn't match the window, then stop.
GetMinWidth: function()
{
// What we'd like it to be
var retval = 750;
// However, if in resizing the window size is different from the document's box object
if (window.innerWidth != document.getElementById('window_parent').boxObject.width)
{
// That means we found the document's min width. Because you can't query it directly.
retval = document.getElementById('window_parent').boxObject.width - 1;
}
return retval;
},
GetMinHeight: function()
{
// What we'd like it to be
var retval = 400;
// However, if in resizing the window size is different from the document's box object
if (window.innerHeight != document.getElementById('window_parent').boxObject.height)
{
// That means we found the document's min width. Because you can't query it directly.
retval = document.getElementById('window_parent').boxObject.height - 1;
}
return retval;
},
GetMaxWidth: function()
{
return -1;
},
GetMaxHeight: function()
{
return -1;
},
QueryInterface : function(aIID)
{
if (!aIID.equals(Components.interfaces.sbIWindowMinMaxCallbacl) &&
!aIID.equals(Components.interfaces.nsISupportsWeakReference) &&
!aIID.equals(Components.interfaces.nsISupports))
{
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
}
}
function setMinMaxCallback()
{
var windowMinMax = Components.classes["@songbird.org/Songbird/WindowMinMax;1"].getService(Components.interfaces.sbIWindowMinMax);
windowMinMax.SetCallback(document, SBWindowMinMaxCB);
}
function checkAltF4(evt)
{
if (evt.keyCode == 0x73 && evt.altKey)
{
evt.preventDefault();
quitApp();
}
}
/**
* Convert a string containing binary values to hex.
*/
function binaryToHex(input)
{
var result = "";
for (var i = 0; i < input.length; ++i)
{
var hex = input.charCodeAt(i).toString(16);
if (hex.length == 1)
hex = "0" + hex;
result += hex;
}
return result;
}
function SBFirstRunPong()
{
const pongURL = "http://www.songbirdnest.com/player/pong";
var firstRun = new sbIDataRemote("application.first_run");
var isFirst = firstRun.GetValue();
if(isFirst == "")
{
var playerUUID = new sbIDataRemote("application.uuid");
var newUUID = playerUUID.GetValue()
if(newUUID == "")
{
var aUUIDGenerator = Components.classes["@mozilla.org/uuid-generator;1"].createInstance(Components.interfaces.nsIUUIDGenerator);
newUUID = aUUIDGenerator.generateUUID();
playerUUID.SetValue(newUUID);
}
var pongRequest = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Components.interfaces.nsIXMLHttpRequest);
var pongHash = Components.classes["@mozilla.org/security/hash;1"].createInstance(Components.interfaces.nsICryptoHash);
var inputStream = Components.classes["@mozilla.org/io/string-input-stream;1"].createInstance(Components.interfaces.nsIStringInputStream);
const confirmShake = "army of darkness rulez";
inputStream.setData(newUUID, -1);
pongHash.initWithString("SHA1");
pongHash.updateFromStream(inputStream, -1);
var uuidHash = binaryToHex(pongHash.finish(false));
confirmShake = uuidHash + confirmShake;
inputStream.setData(confirmShake, -1);
pongHash.initWithString("SHA1");
pongHash.updateFromStream(inputStream, -1);
var confirmHash = binaryToHex(pongHash.finish(false));
var message = "i=" + uuidHash + "&c=" + confirmHash;
var requestURL = pongURL + "?" + message;
pongRequest.open("GET", requestURL, false);
pongRequest.send(null);
if(pongRequest.status == 204)
{
dump("Success!!!");
firstRun.SetValue("false");
}
else
{
dump("Failure!!!");
}
}
}
//
// Core Wrapper Initialization (in XUL, this must happen after the entire page loads).
//
var Poll = null;
function SBInitialize()
{
dump("SBInitialize *** \n");
SBFirstRunPong();
const MediaLibrary = new Components.Constructor("@songbird.org/Songbird/MediaLibrary;1", "sbIMediaLibrary");
const PlaylistManager = new Components.Constructor("@songbird.org/Songbird/PlaylistManager;1", "sbIPlaylistManager");
const PlaylistReaderManager = new Components.Constructor("@songbird.org/Songbird/PlaylistReaderManager;1", "sbIPlaylistReaderManager");
thePlaylistReader = (new PlaylistReaderManager()).QueryInterface(Components.interfaces.sbIPlaylistReaderManager);
try
{
onWindowLoadSize();
setMinMaxCallback();
SBInitPlayerControls();
if (window.addEventListener)
window.addEventListener("keydown", checkAltF4, true);
// Make sure we have a fake database in which to play
aDBQuery = Components.classes["@songbird.org/Songbird/DatabaseQuery;1"];
if (aDBQuery)
{
aDBQuery = aDBQuery.createInstance();
aDBQuery = aDBQuery.QueryInterface(Components.interfaces.sbIDatabaseQuery);
aDBQuery.SetAsyncQuery(false);
aDBQuery.SetDatabaseGUID("testdb-0000");
aDBQuery.AddQuery("create table test (idx integer primary key autoincrement, url text, name text, tim text, artist text, album text, genre text)");
aDBQuery.AddQuery("create index testindex on test(idx, url, name, tim, artist, album, genre)");
var ret = aDBQuery.Execute();
// If it actually worked, that means we created the database
// ask the user if they would like to fill their empty bucket.
if ( ret == 0 )
{
theMediaScanIsOpen.SetValue( true );
setTimeout( SBScanMedia, 1000 );
}
}
// Install listeners on the main pane.
var theMainPane = document.getElementById("frame_main_pane");
if (!mainpane_listener_set)
{
mainpane_listener_set = false;
if (theMainPane.addEventListener) {
theMainPane.addEventListener("DOMContentLoaded", onMainPaneLoad, false);
theMainPane.addEventListener("unload", onMainPaneUnload, true);
theMainPane.addProgressListener(SBDocStartListener);
}
}
// Do something weird to select the first service tree item.
var lastSelection = -1;
if ( SBDataGetValue( "servicetree.selection" ) == "" )
{
lastSelection = 0;
}
var theServiceTree = document.getElementById( 'frame_service_tree' );
restoreServicesCollapsedStates();
theServiceTree.view.selection.currentIndex = lastSelection;
theServiceTree.view.selection.select( lastSelection );
SBServiceTreeListener.m_Tree = theServiceTree;
theServiceTree.builder.addListener( SBServiceTreeListener );
// alert ( SBServiceTreeListener.m_Tree + " " + SBServiceTreeListener.m_Tree.currentIndex );
onServiceTreeRestoreSize();
var lastURI = SBDataGetValue( "browser.uri" );
if ( lastURI != "" )
{
LaunchMainPaneURL( lastURI );
}
theWebPlaylist = document.getElementById( "playlist_web" );
theWebPlaylist.addEventListener( "playlist-play", onPlaylistPlay, true );
// no! theWebPlaylist.addEventListener( "playlist-edit", onPlaylistEdit, true );
theWebPlaylist.addEventListener( "command", onPlaylistContextMenu, false ); // don't force it!
theWebPlaylist.setDnDSourceTracker(sbDnDSourceTracker);
theWebPlaylistQuery = null;
// Poll the playlist source every 250ms to drive the display update (STOOOOPID!)
Poll = new sbIPlaylistsource();
NumPlaylistItemsRemote = new sbIDataRemote( "playlist.numitems" );
NumPlaylistItemsRemote.SetValue( "" );
function PFU()
{
try
{
// Tell the Playlistsource it is allowed to update its observers if it wants.
if ( ! isPlaylistEditShowing )
{
// Poll.UpdateObservers();
}
// Display the number of items in the currently viewed playlist.
var tree_ref = "";
var display_string = "";
// thePlaylistTree is non-null when a playlist is showing.
if ( thePlaylistTree )
{
tree_ref = thePlaylistTree.getAttribute( "ref" );
}
else if ( theWebPlaylistQuery )
{
// If there's a web playlist query, then we can pop the webplaylist.
var mediafound = "Media Found";
try
{
mediafound = theSongbirdStrings.getString("faceplate.mediafound");
} catch(e) {}
var pct = parseInt( SBDataGetValue( "webplaylist.current" ) * 100 / SBDataGetValue( "webplaylist.total" ) );
if ( pct < 100 )
{
display_string = mediafound + " " + pct + "%";
}
else
{
tree_ref = theWebPlaylist.ref;
}
}
if ( tree_ref.length )
{
var rows = Poll.GetRefRowCount( tree_ref );
if ( rows > 0 )
{
var items = "items";
try
{
items = theSongbirdStrings.getString("faceplate.items");
} catch(e) {}
display_string = rows + " " + items;
}
}
NumPlaylistItemsRemote.SetValue( display_string );
}
catch ( err )
{
alert( err );
}
}
setInterval( PFU, 500 );
// var the_url = "ftp://ftp.openbsd.org/pub/OpenBSD/songs";
// var the_url = "http://www.blogotheque.net/mp3/";
// var the_url = "file:///c:\\vice.html";
// var the_url = "http://odeo.com/channel/38104/rss";
// var the_url = "http://takeyourmedicinemp3.blogspot.com/atom.xml";
// var success = thePlaylistReader.AutoLoad(the_url, "songbird", ConvertUrlToDisplayName( the_url ), "http", the_url, "", null);
}
catch(err)
{
alert(err);
}
}
function SBUninitialize()
{
var windowMinMax = Components.classes["@songbird.org/Songbird/WindowMinMax;1"].getService(Components.interfaces.sbIWindowMinMax);
windowMinMax.ResetCallback(document);
}
//
// XUL Event Methods
//
// The background image allows us to move the window around the screen
function onBkgDown( theEvent )
{
var windowDragger = Components.classes["@songbird.org/Songbird/WindowDragger;1"].getService(Components.interfaces.sbIWindowDragger);
windowDragger.BeginWindowDrag(0); // automatically ends
}
function onBkgUp( )
{
var root = "window." + document.documentElement.id;
SBDataSetValue( root + ".x", document.documentElement.boxObject.screenX );
SBDataSetValue( root + ".y", document.documentElement.boxObject.screenY );
}
// old version, just in case
/*var trackerBkg = false;
var offsetScrX = 0;
var offsetScrY = 0;
function onBkgDown( theEvent )
{
trackerBkg = true;
offsetScrX = document.defaultView.screenX - theEvent.screenX;
offsetScrY = document.defaultView.screenY - theEvent.screenY;
document.addEventListener( "mousemove", onBkgMove, true );
}
function onBkgMove( theEvent )
{
if ( trackerBkg )
{
document.defaultView.moveTo( offsetScrX + theEvent.screenX, offsetScrY + theEvent.screenY );
}
}
function onBkgUp( )
{
if ( trackerBkg )
{
trackerBkg = false;
document.removeEventListener( "mousemove", onBkgMove, true );
}
}*/
var URL = new sbIDataRemote("faceplate.play.url");
var thePlaylistIndex = new sbIDataRemote( "playlist.index" );
var seen_playing = new sbIDataRemote("faceplate.seenplaying");
var theTitleText = new sbIDataRemote( "metadata.title" );
var theArtistText = new sbIDataRemote( "metadata.artist" );
var theAlbumText = new sbIDataRemote( "metadata.album" );
var theStatusText = new sbIDataRemote( "faceplate.status.text" );
var theStatusStyle = new sbIDataRemote( "faceplate.status.style" );
// Help
function onHelp()
{
alert( "Aieeeeee, ayudame!" );
}
var theCurrentTrackInterval = null;
function onCurrentTrack()
{
if ( theCurrentTrackInterval )
{
clearInterval( theCurrentTrackInterval );
}
if ( ! thePlaylistTree )
{
// This needs to eventually load the "current playing playlist"
LaunchMainPaneURL( "chrome://rmp_demo/content/main_pane/main_pane.xul?library" );
theCurrentTrackInterval = setInterval( onCurrentTrack, 500 );
}
else
{
SBSyncPlaylistIndex();
}
}
var FaceplateStateData = new sbIDataRemote( "faceplate.state" );
function onNextService()
{
FaceplateStateData.SetValue( ( FaceplateStateData.GetIntValue() + 1 ) % 2 ); // can't use boolean, must use integer logic
}
// onServiceTreeResize
function onServiceTreeResize()
{
var theServiceTree = document.getElementById( "frame_service_tree" );
SBDataSetValue( "servicetree.width", theServiceTree.width );
SBDataSetValue( "servicetree.collapsed", theServiceTree.nextSibling.getAttribute( "state" ) == "collapsed" );
}
// onServiceTreeRestoreSize
function onServiceTreeRestoreSize()
{
var theServiceTree = document.getElementById( "frame_service_tree" );
var width = SBDataGetValue( "servicetree.width" );
if ( width != "" )
{
theServiceTree.width = width;
theServiceTree.nextSibling.setAttribute( "state", SBDataGetIntValue( "servicetree.collapsed" ) ? "collapsed" : "open" );
}
}
// onServiceTreeSelect
var UrlFromServicePane = false;
function onServiceTreeSelect( theEvent )
{
try
{
var theServiceTree = document.getElementById( "frame_service_tree" );
// multiple selection on service tree only happen during the highlighting of an item in drag over, don't switch to the service
if (theServiceTree.getAttribute("seltype") == "multiple") return;
SBDataSetValue( "servicetree.selection", theServiceTree.currentIndex );
if ( theServiceTree.currentIndex >= 0 )
{
// Find the column.
var urlcolumn = theServiceTree.columns ? theServiceTree.columns["url"] : "url";
// Get the text of the hidden tree cell, this contains the url.
var tree_url = theServiceTree.view.getCellText( theServiceTree.currentIndex, urlcolumn );
if ( tree_url.length > 0 )
{
UrlFromServicePane = true;
LaunchMainPaneURL( tree_url );
}
}
}
catch(err)
{
alert( "onServiceTreeSelect - " + err);
}
}
function onServiceTreeClick( theEvent )
{
saveServicesCollapsedStates();
}
function saveServicesCollapsedStates()
{
var theServiceTree = document.getElementById( "frame_service_tree" );
saveCollapsedStates(theServiceTree);
}
function restoreServicesCollapsedStates()
{
var theServiceTree = document.getElementById( "frame_service_tree" );
restoreCollapsedStates(theServiceTree);
}
// onServiceTreeContext
function onServiceTreeContext( theEvent )
{
try
{
var theServiceTree = document.getElementById( "frame_service_tree" );
// First, get the row clicked.
var obj = {};
var row = {};
var col = {};
theServiceTree.treeBoxObject.getCellAt( theEvent.clientX, theEvent.clientY, row, col, obj );
row = row.value;
if ( row >= 0 )
{
// Find the selected element
var element = theServiceTree.contentView.getItemAtIndex( row );
var properties = element.getAttribute( "properties" ).split(" ");
if ( properties.length > 0 )
{
// The first property is the type. Later strings are specific to the type.
switch ( properties[ 0 ] )
{
case "playlist":
onServiceTreeContextPlaylist( theEvent, properties );
break;
default:
onServiceTreeContextDefault( theEvent, properties );
break;
}
}
}
else
{
onServiceTreeContextNone( theEvent );
}
}
catch(err)
{
alert( "onServiceTreeSelect - " + err);
}
}
function onServiceTreeContextPlaylist( theEvent, properties )
{
if ( properties.length >= 5 )
{
var table = properties[ 1 ];
var guid = properties[ 2 ];
var type = properties[ 3 ];
var base_type = properties[ 4 ];
// From these 4 pieces of data, we're going to have to do some idiotically complex stuff.
// Eventually, we'll register a sbIPlaylistCommands with the Servicesource
// For now, make a set of short-circuits to protect our special playlists
if ( table == WEB_PLAYLIST_TABLE && guid == WEB_PLAYLIST_CONTEXT )
{
return;
}
if ( type == "transfer" && base_type == "simple" )
{
return;
}
var theServiceTreePlaylistPopup = document.getElementById( "service_popup_playlist" );
if ( base_type == "smart" )
{
theServiceTreePlaylistPopup = document.getElementById( "service_popup_smart" );
}
if ( base_type == "dynamic" )
{
theServiceTreePlaylistPopup = document.getElementById( "service_popup_smart" );
}
theServiceTreePlaylistPopup.setAttribute( "sb_table", table );
theServiceTreePlaylistPopup.setAttribute( "sb_guid", guid );
theServiceTreePlaylistPopup.setAttribute( "sb_type", type );
theServiceTreePlaylistPopup.setAttribute( "sb_base_type", base_type );
if ( theServiceTreePlaylistPopup )
{
theServiceTreePlaylistPopup.showPopup( document.documentElement, theEvent.screenX, theEvent.screenY, "context", null, null, null );
}
}
}
function onServiceTreeContextDefault( theEvent, properties )
{
}
function onServiceTreeContextNone( theEvent )
{
var theServiceTreePlaylistPopup = document.getElementById( "service_popup_none" );
if ( theServiceTreePlaylistPopup )
{
theServiceTreePlaylistPopup.showPopup( document.documentElement, theEvent.screenX, theEvent.screenY, "context", null, null, null );
}
}
function onServiceTreeCommand( theEvent )
{
if ( theEvent && theEvent.target )
{
// These attribs get set when the menu is popped up on a playlist.
var label = theEvent.target.parentNode.getAttribute( "label" );
var guid = theEvent.target.parentNode.getAttribute( "sb_guid" );
var table = theEvent.target.parentNode.getAttribute( "sb_table" );
var type = theEvent.target.parentNode.getAttribute( "sb_type" );
var base_type = theEvent.target.parentNode.getAttribute( "sb_base_type" );
switch ( theEvent.target.id )
{
case "service_popup_new":
SBNewPlaylist();
break;
case "service_popup_new_smart":
SBNewSmartPlaylist();
break;
case "service_popup_new_remote":
SBSubscribe( "", "", "", "" );
break;
case "playlist_context_smartedit":
if ( base_type == "smart" )
{
if ( guid && guid.length > 0 && table && table.length > 0 )
{
SBNewSmartPlaylist( guid, table );
}
}
if ( base_type == "dynamic" )
{
if ( guid && guid.length > 0 && table && table.length > 0 )
{
SBSubscribe( type, guid, table, label );
}
}
break;
case "playlist_context_rename":
if ( guid && guid.length > 0 && table && table.length > 0 )
{
onServiceEdit();
}
break;
case "playlist_context_remove":
if ( guid && guid.length > 0 && table && table.length > 0 )
{
// Assume we'll need this...
const PlaylistManager = new Components.Constructor("@songbird.org/Songbird/PlaylistManager;1", "sbIPlaylistManager");
var aPlaylistManager = new PlaylistManager();
aPlaylistManager = aPlaylistManager.QueryInterface(Components.interfaces.sbIPlaylistManager);
var aDBQuery = new sbIDatabaseQuery();
aDBQuery.SetAsyncQuery(false);
aDBQuery.SetDatabaseGUID(guid);
switch ( base_type )
{
case "simple":
aPlaylistManager.DeleteSimplePlaylist(table, aDBQuery);
break;
case "dynamic":
aPlaylistManager.DeleteDynamicPlaylist(table, aDBQuery);
break;
case "smart":
aPlaylistManager.DeleteSmartPlaylist(table, aDBQuery);
break;
default:
aPlaylistManager.DeletePlaylist(table, aDBQuery);
break;
}
}
break;
}
}
}
var theServiceTreeScanItems = new Array();
var theServiceTreeScanCount = 0;
function SBScanServiceTreeNewEntryEditable()
{
var theServiceTree = document.getElementById( "frame_service_tree" );
theServiceTreeScanItems.length = 0;
theServiceTreeScanCount = 0;
// Go get all the current service tree urls.
for ( var i = 0; i < theServiceTree.view.rowCount; i++ )
{
theServiceTreeScanItems.push( theServiceTree.contentView.getItemAtIndex( i ).getAttribute( "url" ) );
}
}
function SBScanServiceTreeNewEntryStart()
{
setTimeout( SBScanServiceTreeNewEntryCallback, 500 );
}
function SBScanServiceTreeNewEntryCallback()
{
var theServiceTree = document.getElementById( "frame_service_tree" );
if ( ++theServiceTreeScanCount > 10 )
{
return; // don't loop more than 1 second.
}
// Go through all the current service tree items.
var done = false;
for ( var i = 0; i < theServiceTree.view.rowCount; i++ )
{
var found = false;
var url = theServiceTree.contentView.getItemAtIndex( i ).getAttribute( "url" );
// Match them against the scan items
for ( var j = 0; j < theServiceTreeScanItems.length; j++ )
{
if ( url == theServiceTreeScanItems[ j ] )
{
found = true;
break;
}
}
// Right now, only songbird playlists are editable.
if ( ( ! found ) && ( url.indexOf( ",songbird" ) != -1 ) )
{
// This must be the new one?
theServiceTree.view.selection.currentIndex = i;
theServiceTree.view.selection.select( i );
onServiceEdit();
done = true;
break;
}
}
if ( ! done )
{
setTimeout( SBScanServiceTreeNewEntryCallback, 100 );
}
}
function onServiceEdit()
{
try
{
var theServiceTree = document.getElementById( "frame_service_tree" );
if ( theServiceTree && theServiceTree.currentIndex > -1 )
{
var column = theServiceTree.columns ? theServiceTree.columns["frame_service_tree_label"] : "frame_service_tree_label";
var cell_text = theServiceTree.view.getCellText( theServiceTree.currentIndex, column );
// This is nuts!
var text_x = {}, text_y = {}, text_w = {}, text_h = {};
theServiceTree.treeBoxObject.getCoordsForCellItem( theServiceTree.currentIndex, column, "text",
text_x , text_y , text_w , text_h );
var cell_x = {}, cell_y = {}, cell_w = {}, cell_h = {};
theServiceTree.treeBoxObject.getCoordsForCellItem( theServiceTree.currentIndex, column, "cell",
cell_x , cell_y , cell_w , cell_h );
var image_x = {}, image_y = {}, image_w = {}, image_h = {};
theServiceTree.treeBoxObject.getCoordsForCellItem( theServiceTree.currentIndex, column, "image",
image_x , image_y , image_w , image_h );
var twisty_x = {}, twisty_y = {}, twisty_w = {}, twisty_h = {};
theServiceTree.treeBoxObject.getCoordsForCellItem( theServiceTree.currentIndex, column, "twisty",
twisty_x , twisty_y , twisty_w , twisty_h );
var out_x = {}, out_y = {}, out_w = {}, out_h = {};
out_x = text_x;
out_y = cell_y;
out_w.value = cell_w.value - twisty_w.value - image_w.value;
out_h = cell_h;
// Then pop the edit box to the bounds of the cell.
var theEditPopup = document.getElementById( "service_edit_popup" );
var theEditBox = document.getElementById( "service_edit" );
var extra_x = 3; // Why do I have to give it extra? What am I calculating wrong?
var extra_y = 8; // Why do I have to give it extra? What am I calculating wrong?
var less_w = 5;
var less_h = 0;
var pos_x = extra_x + theServiceTree.boxObject.screenX + out_x.value;
var pos_y = extra_y + theServiceTree.boxObject.screenY + out_y.value;
theEditBox.setAttribute( "hidden", "false" );
theEditPopup.showPopup( theServiceTree, pos_x, pos_y, "popup" );
theEditPopup.sizeTo( out_w.value - less_w, out_h.value - less_h ); // increase the width to the size of the cell.
theEditBox.value = cell_text;
theEditBox.focus();
theEditBox.select();
isServiceEditShowing = true;
}
}
catch ( err )
{
alert( err );
}
}
function onServiceEditChange( evt )
{
try
{
var theServiceTree = document.getElementById( "frame_service_tree" );
if ( theServiceTree && theServiceTree.currentIndex > -1 )
{
var theEditBox = document.getElementById( "service_edit" );
var element = theServiceTree.contentView.getItemAtIndex( theServiceTree.currentIndex );
var properties = element.getAttribute( "properties" ).split(" ");
if ( properties.length >= 5 )
{
var table = properties[ 1 ];
var guid = properties[ 2 ];
var type = properties[ 3 ];
var base_type = properties[ 4 ];
const PlaylistManager = new Components.Constructor("@songbird.org/Songbird/PlaylistManager;1", "sbIPlaylistManager");
var aPlaylistManager = (new PlaylistManager()).QueryInterface(Components.interfaces.sbIPlaylistManager);
var aDBQuery = new sbIDatabaseQuery();
aDBQuery.SetAsyncQuery(false);
aDBQuery.SetDatabaseGUID(guid);
var playlist = null;
// How do I edit a table's readable name? I have to know what type it is? Ugh.
switch ( base_type )
{
case "simple": playlist = aPlaylistManager.GetSimplePlaylist(table, aDBQuery); break;
case "dynamic": playlist = aPlaylistManager.GetDynamicPlaylist(table, aDBQuery); break;
case "smart": playlist = aPlaylistManager.GetSmartPlaylist(table, aDBQuery); break;
default: playlist = aPlaylistManager.GetPlaylist(table, aDBQuery); break;
}
if(playlist)
{
var strReadableName = evt.target.value;
playlist.SetReadableName(strReadableName);
}
}
HideServiceEdit();
}
}
catch ( err )
{
alert( err );
}
}
function onServiceEditKeypress( evt )
{
switch ( evt.keyCode )
{
case 27: // Esc
HideServiceEdit();
break;
case 13: // Return
onServiceEditChange( evt );
break;
}
}
var isServiceEditShowing = false;
function HideServiceEdit()
{
try
{
if ( isServiceEditShowing )
{
var theEditBox = document.getElementById( "service_edit" );
theEditBox.setAttribute( "hidden", "true" );
var theEditPopup = document.getElementById( "service_edit_popup" );
theEditPopup.hidePopup();
isServiceEditShowing = false;
}
}
catch ( err )
{
alert( err );
}
}
var theCanGoBackData = new sbIDataRemote("browser.cangoback");
var theCanGoFwdData = new sbIDataRemote("browser.cangofwd");
var theCanAddToPlaylistData = new sbIDataRemote( "browser.canplaylist" );
var theBrowserUrlData = new sbIDataRemote( "browser.url.text" );
var theBrowserImageData = new sbIDataRemote( "browser.url.image" );
var theBrowserUriData = new sbIDataRemote( "browser.uri" );
var theShowWebPlaylistData = new sbIDataRemote( "browser.playlist.show" );
var SBDocStartListener = {
m_CurrentRequestURI: "",
QueryInterface : function(aIID) {
if (!aIID.equals(Components.interfaces.nsIWebProgressListener) &&
!aIID.equals(Components.interfaces.nsISupportsWeakReference) &&
!aIID.equals(Components.interfaces.nsISupports))
{
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
onStateChange : function( aWebProgress, aRequest, aState, aStatus )
{
const STATE_STOP = 0x10;
const STATE_IS_DOCUMENT = 0x20000;
try
{
if ( ( ( aState & ( STATE_STOP | STATE_IS_DOCUMENT ) ) != 0 ) && ( aStatus == 0x804B001E ) ) // ? 0x804B001E?
{
LaunchMainPaneURL( "chrome://rmp_demo/content/cannot_load.html" );
}
}
catch ( err )
{
alert( "onStateChange - " + err );
}
},
onStatusChange : function( aWebProgress, aRequest, aLocation )
{
},
onProgressChange : function( aWebProgress, aRequest, aLocation )
{
},
onSecurityChange : function( aWebProgress, aRequest, aLocation )
{
},
onLocationChange : function( aWebProgress, aRequest, aLocation )
{
try
{
// Set the value in the text box (shown or not)
var theMainPane = document.getElementById( "frame_main_pane" );
var cur_uri = aLocation.asciiSpec;
m_CurrentRequestURI = aRequest.name;
// if ( SBGetUrlFromService( theBrowserUrlData.GetValue() ) != cur_uri )
{
// Set the box
theBrowserUriData.SetValue( cur_uri );
theBrowserUrlData.SetValue( SBGetServiceFromUrl( cur_uri ) );
var image = SBGetServiceImageFromUrl( cur_uri );
if ( image.length )
{
theBrowserImageData.SetValue( image );
}
// Set the buttons based on the session history.
if ( theMainPane.webNavigation.sessionHistory )
{
// Check the buttons
theCanGoBackData.SetValue( theMainPane.webNavigation.canGoBack );
theCanGoFwdData.SetValue( theMainPane.webNavigation.canGoForward )
}
else
{
// Error?
}
/*
// Hide or show the HTML box based upon whether or not the loaded page is .xul (lame heuristic)
var theHTMLBox = document.getElementById( "frame_main_pane_html" );
if ( theHTMLBox )
{
if ( cur_uri.indexOf(".xul") != -1 )
{
if ( SBDataGetIntValue( "option.htmlbar" ) == 0 )
{
theHTMLBox.setAttribute( "hidden", "true" );
}
}
else
{
theHTMLBox.setAttribute( "hidden", "false" );
}
}
*/
}
if ( ! UrlFromServicePane )
{
// Clear the service tree selection (asynchronously? is this from out of thread?)
setTimeout(
"document.getElementById( 'frame_service_tree' ).view.selection.currentIndex = -1;" +
"document.getElementById( 'frame_service_tree' ).view.selection.clearSelection();",
50 );
}
UrlFromServicePane = false;
thePaneLoadingData.SetValue( true );
// Clear the playlist tree variable so we are not confused.
thePlaylistTree = null;
theLibraryPlaylist = null;
// Clear the tracking variable
mainpane_listener_set = false;
// Disable the "add to playlist" button until we see that there is anything to add.
theCanAddToPlaylistData.SetValue( false );
onBrowserPlaylistHide();
// Clear the playlist tree variable so we are not confused.
thePlaylistTree = null;
theLibraryPlaylist = null;
// Nothing in the status text
theStatusText.SetValue( "" );
}
catch ( err )
{
alert( err );
}
}
}
var theCurrentURL = "";
function LaunchMainPaneURL( the_url )
{
try
{
// And if it's a good string, launch it.
if ( ( the_url ) && ( the_url.indexOf ) && ( the_url.length > 0 ) && ( theCurrentURL != the_url ) )
{
var theMainPane = document.getElementById( "frame_main_pane" );
// Set the src attribute to load the url
theCurrentURL = the_url;
// onMainPaneTransfer();
/*
// If the last page was a xul page, replace this history entry by the new URI, so that the old chrome is actually deleted, otherwise it will keep
// running in the background eventho it has been unlinked from the DOM, it will generate plenty of errors since some of the functions it uses may
// be attached to DOM objects (ie, window.alert), and it will never be deleted, even when the application closes (ie, none of its xbl bindings
// destructors will be called, ever). This has the effect of excluding the playlist view (and any xul chrome) from the history altogether, ie,
// if you switch to a webpage, then to the library, then to a webpage again, clicking the back button on the browser will bring you back to the
// first webpage.
if ( theMainPane.currentURI.spec.indexOf(".xul") != -1 )
{
theMainPane.loadURIWithFlags( theCurrentURL, LOAD_FLAGS_BYPASS_HISTORY, null, null );
}
else
*/
{
try
{
theMainPane.loadURI( theCurrentURL, null, null );
}
catch (e)
{
// Grrrr.
}
}
}
}
catch ( err )
{
alert( err );
}
}
// onBrowserBack
function onBrowserBack()
{
// Disable the "add to playlist" button until we see that there is anything to add.
theCanAddToPlaylistData.SetValue( false );
onBrowserPlaylistHide();
var theMainPane = document.getElementById( "frame_main_pane" );
mainpane_listener_set = false;
theMainPane.goBack();
}
// onBrowserFwd
function onBrowserFwd()
{
// Disable the "add to playlist" button until we see that there is anything to add.
theCanAddToPlaylistData.SetValue( false );
onBrowserPlaylistHide();
var theMainPane = document.getElementById( "frame_main_pane" );
mainpane_listener_set = false;
theMainPane.goForward();
}
// onBrowserRefresh
function onBrowserRefresh()
{
try
{
var theMainPane = document.getElementById( "frame_main_pane" );
mainpane_listener_set = false;
theMainPane.reload();
}
catch( err )
{
alert( err );
}
}
// onBrowserStop
function onBrowserStop()
{
try
{
var theMainPane = document.getElementById( "frame_main_pane" );
theMainPane.stop();
mainpane_listener_set = false;
onMainPaneLoad();
}
catch( err )
{
alert( err );
}
}
// onBrowserHome
function onBrowserHome()
{
LaunchMainPaneURL( "http://songbirdnest.com/player/welcome/" );
}
var SBWebPlaylistCommands =
{
m_Playlist: null,
m_Ids: new Array
(
"library_cmd_play",
// "library_cmd_edit",
"library_cmd_download",
"library_cmd_subscribe",
"library_cmd_addtoplaylist",
"library_cmd_addtolibrary",
"library_cmd_burntocd",
"library_cmd_device"
),
m_Names: new Array
(
"&command.play",
// "&command.edit",
"&command.download",
"&command.subscribe",
"&command.addtoplaylist",
"&command.addtolibrary",
"&command.burntocd",
"&command.device"
),
m_Tooltips: new Array
(
"&command.tooltip.play",
// "&command.tooltip.edit",
"&command.tooltip.download",
"&command.tooltip.subscribe",
"&command.tooltip.addtoplaylist",
"&command.tooltip.addtolibrary",
"&command.tooltip.burntocd",
"&command.tooltip.device"
),
GetNumCommands: function()
{
if (
( this.m_Tooltips.length != this.m_Ids.length ) ||
( this.m_Names.length != this.m_Ids.length ) ||
( this.m_Tooltips.length != this.m_Names.length )
)
{
alert( "PlaylistCommands - Array lengths do not match!" );
return 0;
}
return this.m_Ids.length;
},
GetCommandId: function( index )
{
if ( index >= this.m_Ids.length )
{
return "";
}
return this.m_Ids[ index ];
},
GetCommandText: function( index )
{
if ( index >= this.m_Names.length )
{
return "";
}
return this.m_Names[ index ];
},
GetCommandToolTipText: function( index )
{
if ( index >= this.m_Tooltips.length )
{
return "";
}
return this.m_Tooltips[ index ];
},
GetCommandEnabled: function( index )
{
var retval = false;
switch ( this.m_Ids[index] )
{
case "library_cmd_burntocd":
case "library_cmd_device":
retval = false; // not yet implemented
break;
default:
retval = true;
break;
}
return retval;
},
OnCommand: function( event )
{
if ( event.target && event.target.id )
{
// Was it from the toolbarbutton?
var tbb = ( event.target.tagName == "toolbarbutton" || event.target.tagName == "xul:toolbarbutton" );
switch( event.target.id )
{
case "library_cmd_play":
if ( this.m_Playlist.tree.currentIndex != -1 )
{
// Repurpose the command to act as if a doubleclick
this.m_Playlist.sendPlayEvent();
}
break;
case "library_cmd_edit":
if ( this.m_Playlist.tree.currentIndex != -1 )
{
if ( tbb )
{
// Open the editor for the whole track
}
else
{
// Edit the context cell
this.m_Playlist.sendEditEvent();
}
}
break;
case "library_cmd_download":
{
try
{
var filterCol = "uuid";
var filterVals = new Array();
var columnObj = this.m_Playlist.tree.columns.getNamedColumn(filterCol);
var rangeCount = this.m_Playlist.tree.view.selection.getRangeCount();
for (var i=0; i < rangeCount; i++)
{
var start = {};
var end = {};
this.m_Playlist.tree.view.selection.getRangeAt( i, start, end );
for( var c = start.value; c <= end.value; c++ )
{
if (c >= this.m_Playlist.tree.view.rowCount)
{
// alert( c + ">=" + this.m_Playlist.tree.view.rowCount );
continue;
}
var value = this.m_Playlist.tree.view.getCellText(c, columnObj);
filterVals.push(value);
}
}
/*
for(var i in filterVals)
{
alert(filterVals[i]);
}
*/
onBrowserTransfer( this.m_Playlist.guid, this.m_Playlist.table, filterCol, filterVals.length, filterVals );
// And show the download table in the chrome playlist.
//onBrowserDownload();
}
catch( err )
{
alert( err );
}
}
break;
case "library_cmd_subscribe":
{
// Bring up the subscribe dialog with the web playlist url
var url = this.m_Playlist.type;
var readable_name = null;
var guid = null;
var table = null;
if ( url == "http" )
{
url = this.m_Playlist.description;
readable_name = this.m_Playlist.readable_name;
guid = this.m_Playlist.guid;
table = this.m_Playlist.table;
}
SBSubscribe( url, guid, table, readable_name );
}
break;
case "library_cmd_addtoplaylist":
{
this.m_Playlist.addToPlaylist();
}
break;
case "library_cmd_addtolibrary":
{
this.m_Playlist.addToLibrary();
}
break;
}
}
},
// The object registered with the sbIPlaylistSource interface acts
// as a template for instances bound to specific playlist elements
Duplicate: function()
{
var obj = {};
for ( var i in this )
{
obj[ i ] = this[ i ];
}
return obj;
},
SetPlaylist: function( playlist )
{
this.m_Playlist = playlist;
},
QueryInterface : function(aIID)
{
if (!aIID.equals(Components.interfaces.sbIPlaylistCommands) &&
!aIID.equals(Components.interfaces.nsISupportsWeakReference) &&
!aIID.equals(Components.interfaces.nsISupports))
{
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
}
}
// Register the web playlist commands at startup
if ( ( WEB_PLAYLIST_CONTEXT != "" ) && ( WEB_PLAYLIST_TABLE != "" ) )
{
var source = new sbIPlaylistsource();
source.RegisterPlaylistCommands( WEB_PLAYLIST_CONTEXT, WEB_PLAYLIST_TABLE, "http", SBWebPlaylistCommands );
}
function onBrowserPlaylist()
{
if ( ! thePlaylistTree )
{
var hidden = theShowWebPlaylistData.GetIntValue() == 0;
var show = hidden; // flip state?
// And tell the playlist to point at the web table
var ui_id = "playlist_web"
if ( theWebPlaylist.ref != ( "NC:" + WEB_PLAYLIST_CONTEXT + "_" + WEB_PLAYLIST_TABLE ) )
{
SBWebPlaylistCommands.m_Playlist = theWebPlaylist;
theWebPlaylist.bind( WEB_PLAYLIST_CONTEXT, WEB_PLAYLIST_TABLE, null, SBWebPlaylistCommands, SBDataGetValue( "browser.playlist.height" ), SBDataGetValue( "browser.playlist.collapsed" ) );
show = true;
}
// Show/hide them
theShowWebPlaylistData.SetValue( show );
}
}
function onBrowserPlaylistResize()
{
SBDataSetValue( "browser.playlist.height", theWebPlaylist.height );
var collapsed = theWebPlaylist.previousSibling.getAttribute( "state" ) == "collapsed";
SBDataSetValue( "browser.playlist.collapsed", collapsed );
}
function onBrowserDownload()
{
if ( ! thePlaylistTree )
{
var hidden = theShowWebPlaylistData.GetIntValue() == 0;
var show = hidden; // flip state?
var ui_id = "playlist_web"
var guid = theDownloadContext.GetValue();
var table = theDownloadTable.GetValue();
// Errrr, nope?
if ( ( guid == "" ) || ( table == "" ) )
{
return;
}
if ( theWebPlaylist.ref != ( "NC:" + guid + "_" + table ) )
{
theWebPlaylist.bind( guid, table, null, SBDownloadCommands );
show = true;
}
// Show/hide them
theShowWebPlaylistData.SetValue( show );
}
}
function onBrowserPlaylistHide()
{
// Don't need this anymore
theWebPlaylistQuery = null;
// Hide the web table if it exists
theShowWebPlaylistData.SetValue( false );
// And unhook the playlist from the database
var theTree = document.getElementById( "playlist_web" );
if ( theTree )
{
var source = new sbIPlaylistsource();
source.ClearPlaylist( theTree.ref );
theTree.datasources = "";
theTree.ref = "";
}
}
// onHTMLUrlChange
function onHTMLUrlChange( evt )
{
var value = evt.target.value;
if ( value && value.length )
{
// Make sure the value is an url
value = SBGetUrlFromService( value );
// And then put it back in the box as a service
theBrowserUriData.SetValue( value );
theBrowserUrlData.SetValue( SBGetServiceFromUrl( value ) );
var image = SBGetServiceImageFromUrl( value );
if ( image.length )
{
theBrowserImageData.SetValue( image );
}
// And then go to the url. Easy, no?
LaunchMainPaneURL( value );
}
}
function onHTMLUrlKeypress( evt )
{
switch ( evt.keyCode )
{
case 13: // Enter
evt.target.value = SBTabcompleteService( evt.target.value );
onHTMLUrlChange( evt );
break;
/*
case 9: // Tab
var value = SBTabcompleteService( evt.target.value );
if ( value != evt.target.value )
{
alert ( value + " != " + evt.target.value )
evt.target.value = value;
onHTMLUrlChange( evt );
}
break;
*/
}
}
var mainpane_listener_set = false;
var thePlaylistRef = new sbIDataRemote( "playlist.ref" );
var thePaneLoadingData = new sbIDataRemote( "faceplate.loading" );
thePaneLoadingData.SetValue( false );
var thePlaylistTree;
var theCurrentMainPaneDocument = null;
function onMainPaneLoad()
{
try
{
if ( ! mainpane_listener_set )
{
var theMainPane = document.getElementById( "frame_main_pane" );
if ( typeof( theMainPane ) == 'undefined' )
{
return;
}
//
//
// HORRIBLE SECURITY HACK TO GET THE PLAYLIST TREE AND INJECT FUN EVENT HANDLERS
//
//
var installed_listener = false;
var main_iframe = theMainPane.contentDocument.getElementById( "main_iframe" );
if ( main_iframe )
{
if ( main_iframe.wrappedJSObject )
main_iframe = main_iframe.wrappedJSObject;
// Doublecheck that the playlist piece loaded properly?
if ( ( ! main_iframe.contentDocument ) || ( ! main_iframe.contentDocument.getElementById ) )
{
// Try again in 250 ms?
setTimeout( onMainPaneLoad, 250 );
return;
}
thePlaylistTree = main_iframe.contentDocument.getElementById( "playlist_test" );
if ( thePlaylistTree )
{
// Crack the security if necessary
if ( thePlaylistTree.wrappedJSObject )
thePlaylistTree = thePlaylistTree.wrappedJSObject;
// Wait until after the bind call?
if ( thePlaylistTree.ref == "" )
{
// Try again in 250 ms?
setTimeout( onMainPaneLoad, 250 );
return;
}
// Drag and Drop tracker object
thePlaylistTree.setDnDSourceTracker(sbDnDSourceTracker);
// Events on the playlist object itself.
thePlaylistTree.addEventListener( "playlist-edit", onPlaylistEdit, true );
thePlaylistTree.addEventListener( "playlist-play", onPlaylistPlay, true );
thePlaylistTree.addEventListener( "command", onPlaylistContextMenu, false ); // don't force it!
// Remember some values
theLibraryPlaylist = thePlaylistTree;
thePlaylistTree = thePlaylistTree.tree;
thePlaylistRef.SetValue( thePlaylistTree.getAttribute( "ref" ) ); // is this set yet?
// Set the current selection
SBSyncPlaylistIndex();
// And remember that we did this
installed_listener = true;
// Hide the progress bar now that we're loaded.
thePaneLoadingData.SetValue( false );
mainpane_listener_set = true;
}
}
else
{
thePlaylistTree = null;
theLibraryPlaylist = null;
}
// If we don't install a playlist listener, install an url listener.
if ( ! installed_listener )
{
if ( theMainPane.contentDocument && theMainPane.contentDocument.getElementsByTagName('A').length == 0 )
{
setTimeout( onMainPaneLoad, 2500 );
return;
}
AsyncWebDocument( theMainPane.contentDocument );
// Hide the progress bar now that we're loaded.
thePaneLoadingData.SetValue( false );
mainpane_listener_set = true;
}
}
}
catch( err )
{
alert( err );
}
}
function onMainPaneUnload()
{
try
{
}
catch( err )
{
alert( err );
}
}
function IsMediaUrl( the_url )
{
if ( ( the_url.indexOf ) &&
(
// Protocols at the beginning
( the_url.indexOf( "mms:" ) == 0 ) ||
( the_url.indexOf( "rtsp:" ) == 0 ) ||
// File extensions at the end
( the_url.indexOf( ".pls" ) != -1 ) ||
( the_url.indexOf( ".m3u" ) == ( the_url.length - 4 ) ) ||
// ( the_url.indexOf( ".rm" ) == ( the_url.length - 3 ) ) ||
// ( the_url.indexOf( ".ram" ) == ( the_url.length - 4 ) ) ||
// ( the_url.indexOf( ".smil" ) == ( the_url.length - 5 ) ) ||
( the_url.indexOf( ".mp3" ) == ( the_url.length - 4 ) ) ||
( the_url.indexOf( ".ogg" ) == ( the_url.length - 4 ) ) ||
( the_url.indexOf( ".wma" ) == ( the_url.length - 4 ) ) ||
( the_url.indexOf( ".wmv" ) == ( the_url.length - 4 ) ) ||
( the_url.indexOf( ".asx" ) == ( the_url.length - 4 ) ) ||
( the_url.indexOf( ".asf" ) == ( the_url.length - 4 ) ) ||
( the_url.indexOf( ".avi" ) == ( the_url.length - 4 ) ) ||
( the_url.indexOf( ".mov" ) == ( the_url.length - 4 ) ) ||
( the_url.indexOf( ".mp4" ) == ( the_url.length - 4 ) )
)
)
{
return true;
}
return false;
}
function IsPlaylistUrl( the_url )
{
try
{
if ( the_url.indexOf )
{
// Make the playlist reader manager.
const PlaylistReaderManager = new Components.Constructor("@songbird.org/Songbird/PlaylistReaderManager;1", "sbIPlaylistReaderManager");
var aPlaylistReaderManager = (new PlaylistReaderManager()).QueryInterface(Components.interfaces.sbIPlaylistReaderManager);
// Tell it what filters to be using
var filterlist = "";
var extensionCount = new Object;
var extensions = aPlaylistReaderManager.SupportedFileExtensions(extensionCount);
for(var i = 0; i < extensions.length; i++)
{
if ( the_url.indexOf( "." + extensions[i] ) != -1 )
{
return true;
}
}
}
}
catch ( err )
{
alert( "IsPlaylistUrl - " + err );
}
return false;
}
function GetHrefFromEvent( evt )
{
var the_href = "";
try
{
var node = evt.target;
while ( node ) // Walk up from the event target to find the A?
{
if ( node.href )
{
the_href = node.href;
break;
}
node = node.parentNode;
}
}
catch ( err )
{
alert( err );
}
return the_href;
}
// Catch a contextual on a media url and attempt to play it
function onLinkOver( evt )
{
var the_url = GetHrefFromEvent( evt )
theStatusText.SetValue( the_url );
if ( IsMediaUrl( the_url ) )
{
theStatusStyle.SetValue( "font-weight: bold;" );
}
else
{
theStatusStyle.SetValue( "font-weight: normal;" );
}
}
// Catch a contextual on a media url and attempt to play it
function onLinkOut( evt )
{
theStatusText.SetValue( "" );
}
// Catch a contextual on a media url and attempt to play it
var theHTMLContextURL = null;
function onLinkContext( evt )
{
try
{
var theMainPane = document.getElementById( "frame_main_pane" );
var theHTMLPopup = document.getElementById( "html_context_menu" );
theHTMLContextURL = GetHrefFromEvent( evt );
var theAddItem = document.getElementById( "html.context.add" );
var disabled = "true";
if ( IsMediaUrl( theHTMLContextURL ) && ! SBUrlExistsInDatabase( theHTMLContextURL ) )
{
disabled = "false"
}
theAddItem.setAttribute( "disabled", disabled );
theHTMLPopup.showPopup( theMainPane, theMainPane.boxObject.screenX + evt.clientX, theMainPane.boxObject.screenY + evt.clientY, "context", null, null );
}
catch ( err )
{
alert( err );
}
}
// Catch a click on a media url and attempt to play it
function onMediaClick( evt )
{
try
{
var the_url = GetHrefFromEvent( evt );
if ( IsMediaUrl( the_url ) )
{
URL.SetValue(the_url);
playCurrentUrl( true );
evt.stopPropagation();
evt.preventDefault();
}
}
catch ( err )
{
alert( err );
}
}
function onPlaylistKeypress( evt )
{
switch ( evt.keyCode )
{
case 13: // Return
SBPlayPlaylistIndex( thePlaylistTree.currentIndex );
break;
}
}
// Yo, play something, bitch.
function onPlaylistPlay( evt )
{
var target = evt.target;
if ( target.wrappedJSObject )
{
target = target.wrappedJSObject;
}
SBPlayPlaylistIndex( target.tree.currentIndex, target );
}
function onPlaylistDblClick( evt )
{
if ( typeof( thePlaylistTree ) == 'undefined' )
{
alert( "DOM?" );
return;
}
var obj = {}, row = {}, col = {};
thePlaylistTree.treeBoxObject.getCellAt( evt.clientX, evt.clientY, row, col, obj );
// If the "obj" has a value, it is a cell?
if ( obj.value )
{
if ( thePlaylistTree.currentIndex != -1 )
{
SBPlayPlaylistIndex( thePlaylistTree.currentIndex );
}
}
}
function SBDownloadDeviceTest()
{
try
{
aDownloadDevice = Components.classes["@songbird.org/Songbird/DownloadDevice;1"];
if (aDownloadDevice)
{
aDownloadDevice = aDownloadDevice.createInstance();
aDownloadDevice = aDownloadDevice.QueryInterface(Components.interfaces.sbIDeviceBase);
if (aDownloadDevice)
{
listProperties( aDownloadDevice, "aDownloadDevice" );
alert( Components.interfaces.sbIDownloadDevice );
aDownloadDevice.name;
aDownloadDevice.IsDownloadSupported();
t = aDownloadDevice.DownloadTrackTable('testdb-0000','download');
}
}
}
catch ( err )
{
alert( err );
}
}
var theCurrentlyEditingPlaylist = null;
function onPlaylistEdit( evt )
{
try
{
var playlist = evt.target;
if ( playlist.wrappedJSObject )
playlist = playlist.wrappedJSObject;
// Make sure it's something with a uuid column.
var filter = "uuid";
var filter_column = playlist.tree.columns ? playlist.tree.columns[filter] : filter;
var filter_value = playlist.tree.view.getCellText( playlist.tree.currentIndex, filter_column );
if ( !filter_value )
{
return;
}
// We want to resize the edit box to the size of the cell.
var out_x = {}, out_y = {}, out_w = {}, out_h = {};
playlist.tree.treeBoxObject.getCoordsForCellItem( playlist.edit_row, playlist.edit_col, "cell",
out_x , out_y , out_w , out_h );
var cell_text = playlist.tree.view.getCellText( playlist.edit_row, playlist.edit_col );
// Then pop the edit box to the bounds of the cell.
var theMainPane = document.getElementById( "frame_main_pane" );
var theEditPopup = document.getElementById( "playlist_edit_popup" );
var theEditBox = document.getElementById( "playlist_edit" );
var extra_x = 4; // Why do I have to give it extra? What am I calculating wrong?
var extra_y = 21; // Why do I have to give it extra? What am I calculating wrong?
var less_w = 5;
var less_h = 0;
var pos_x = extra_x + playlist.tree.boxObject.screenX + out_x.value;
var pos_y = extra_y + playlist.tree.boxObject.screenY + out_y.value;
theEditBox.setAttribute( "hidden", "false" );
theEditPopup.showPopup( theMainPane, pos_x, pos_y, "context" );
theEditPopup.sizeTo( out_w.value - less_w, out_h.value - less_h ); // increase the width to the size of the cell.
theEditBox.value = cell_text;
theEditBox.focus();
theEditBox.select();
isPlaylistEditShowing = true;
theCurrentlyEditingPlaylist = playlist;
}
catch ( err )
{
alert( err );
}
}
function onPlaylistEditChange( evt )
{
try
{
var theEditBox = document.getElementById( "playlist_edit" );
// Find the url column.
var filter = "uuid";
var filter_column = theCurrentlyEditingPlaylist.tree.columns ? theCurrentlyEditingPlaylist.tree.columns[filter] : filter;
var filter_value = theCurrentlyEditingPlaylist.tree.view.getCellText( theCurrentlyEditingPlaylist.tree.currentIndex, filter_column );
var the_table_column = theCurrentlyEditingPlaylist.edit_col.id;
var the_new_value = theEditBox.value
var aDBQuery = Components.classes["@songbird.org/Songbird/DatabaseQuery;1"].createInstance(Components.interfaces.sbIDatabaseQuery);
var aMediaLibrary = Components.classes["@songbird.org/Songbird/MediaLibrary;1"].createInstance(Components.interfaces.sbIMediaLibrary);
if ( ! aDBQuery || ! aMediaLibrary)
return;
aDBQuery.SetAsyncQuery(true);
aDBQuery.SetDatabaseGUID(theCurrentlyEditingPlaylist.guid);
aMediaLibrary.SetQueryObject(aDBQuery);
aMediaLibrary.SetValueByGUID(filter_value, the_table_column, the_new_value, false);
//var table = "library" // hmm... // theCurrentlyEditingPlaylist.table;
//var q = 'update ' + table + ' set ' + the_table_column + '="' + the_new_value + '" where ' + filter + '="' + filter_value + '"';
//aDBQuery.AddQuery( q );
//var ret = aDBQuery.Execute();
HidePlaylistEdit();
}
catch ( err )
{
alert( err );
}
}
function onPlaylistEditKeypress( evt )
{
switch ( evt.keyCode )
{
case 27: // Esc
HidePlaylistEdit();
break;
case 13: // Return
onPlaylistEditChange( evt );
break;
}
}
var isPlaylistEditShowing = false;
function HidePlaylistEdit()
{
try
{
if ( isPlaylistEditShowing )
{
var theEditBox = document.getElementById( "playlist_edit" );
theEditBox.setAttribute( "hidden", "true" );
var theEditPopup = document.getElementById( "playlist_edit_popup" );
theEditPopup.hidePopup();
isPlaylistEditShowing = false;
theCurrentlyEditingPlaylist = null;
}
}
catch ( err )
{
alert( err );
}
}
// Menubar handling
function onPlaylistContextMenu( evt )
{
try
{
// hacky for now
var playlist = theLibraryPlaylist;
if ( !playlist )
{
playlist = theWebPlaylist;
}
// All we do up here, now, is dispatch the search items
onSearchTerm( playlist.context_item, playlist.context_term );
}
catch ( err )
{
alert( err );
}
}
function onSearchTerm( target, in_term )
{
var search_url = "";
if ( in_term && in_term.length )
{
// var term = '"' + in_term + '"';
var term = in_term;
var v = target.getAttribute( "id" );
switch ( v )
{
case "search.popup.songbird":
onSearchEditIdle();
break;
case "search.popup.google":
search_url = "http://www.google.com/musicsearch?q=" + term + "&sa=Search";
break;
case "search.popup.wiki":
search_url = "http://en.wikipedia.org/wiki/Special:Search?search=" + term;
break;
case "search.popup.yahoo":
search_url = "http://audio.search.yahoo.com/search/audio?ei=UTF-8&fr=sfp&p=" + term;
break;
case "search.popup.emusic":
search_url = "http://www.emusic.com/search.html?mode=x&QT=" + term + "&x=0&y=0";
break;
case "search.popup.insound":
search_url = "http://search.insound.com/search/searchmain.jsp?searchby=meta&query=" + term + "&fromindex=1&submit.x=0&submit.y=0";
break;
case "search.popup.odeo":
search_url = "http://odeo.com/search/query/?q=" + term + "&Search.x=0&Search.y=0";
break;
case "search.popup.shoutcast":
search_url = "http://www.shoutcast.com/directory/?s=" + term;
break;
case "search.popup.radiotime":
search_url = "http://radiotime.com/toppicks.aspx?p=0&st=0&t=" + term;
break;
case "lyrics.popup.google":
search_url = "http://www.google.com/search?q=lyrics " + term + "&sa=Search&client=pub-4053348708517670&forid=1&ie=ISO-8859-1&oe=ISO-8859-1&hl=en&GALT:#333333;GL:1;DIV:#37352E;VLC:000000;AH:center;BGC:C6B396;LBGC:8E866F;ALC:000000;LC:000000;T:44423A;GFNT:663333;GIMP:663333;FORID:1;";
break;
}
}
if ( search_url.length )
{
LaunchMainPaneURL( search_url );
}
}
var repeat = new sbIDataRemote( "playlist.repeat" );
// Menubar handling
function onMenu( target )
{
var v = target.getAttribute( "id" );
switch ( v )
{
case "file.new":
SBNewPlaylist();
break;
case "file.smart":
SBNewSmartPlaylist();
break;
case "file.remote":
SBSubscribe( "", "", "", "" );
break;
case "file.file":
SBFileOpen();
break;
case "file.url":
SBUrlOpen();
break;
case "file.mab":
SBMabOpen();
break;
case "file.playlist":
SBPlaylistOpen();
break;
case "file.scan":
SBScanMedia();
break;
case "file.dlfolder":
SBSetDownloadFolder();
break;
case "file.watch":
SBWatchFolders();
break;
/*
case "file.htmlbar":
if ( SBDataGetIntValue( "option.htmlbar" ) == 0 )
{
SBDataSetValue( "option.htmlbar", 1 );
}
else
{
SBDataSetValue( "option.htmlbar", 0 );
}
break;
*/
case "file.skin":
try
{
var root = "window." + document.documentElement.id;
SBDataSetValue( root + ".x", document.documentElement.boxObject.screenX );
SBDataSetValue( root + ".y", document.documentElement.boxObject.screenY );
SBDataSetValue( root + ".w", document.documentElement.boxObject.width );
SBDataSetValue( root + ".h", document.documentElement.boxObject.height );
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
if ( SBDataGetIntValue( "option.skin" ) == 0 )
{
onMinimize();
SBDataSetValue( "option.skin", 1 );
prefs.setCharPref("general.skins.selectedSkin", "otherskin");
window.open( "chrome://rmp_demo/content/mainwin.xul", "", "chrome,modal=no" );
setTimeout( "onExit();", 1000 );
}
else
{
onMinimize();
SBDataSetValue( "option.skin", 0 );
prefs.setCharPref("general.skins.selectedSkin", "songbird");
window.open( "chrome://rmp_demo/content/mainwin.xul", "", "chrome,modal=no" );
setTimeout( "onExit();", 1000 );
}
}
catch ( err )
{
alert( err );
}
break;
case "file.window":
SBMiniplayerOpen();
break;
case "file.koshi":
SBKoshiOpen();
break;
case "file.about":
About();
break;
case "file.exit":
quitApp();
break;
case "control.play":
if ( ! myPlayerRemote.isPlaying() )
{
onPlay();
}
else
{
onPause();
}
break;
case "control.next":
onFwd();
break;
case "control.prev":
onBack();
break;
case "control.shuf":
onShuffle();
break;
case "control.repa":
repeat.SetValue( 2 );
break;
case "control.rep1":
repeat.SetValue( 1 );
break;
case "control.repx":
repeat.SetValue( 0 );
break;
case "menu.extensions":
SBExtensionsManagerOpen();
break;
/* case "menu.dominspector":
SBDOMInspectorOpen();
break;*/
default:
if ( target.value )
{
LaunchMainPaneURL( target.value );
}
break;
}
}
function SBSetDownloadFolder()
{
// Just open the window, we don't care what the user does in it.
SBOpenModalDialog( "chrome://rmp_demo/content/download.xul", "", "chrome,modal=yes,centerscreen", null );
}
function SBWatchFolders()
{
SBOpenModalDialog( "chrome://rmp_demo/content/watch_folders.xul", "", "chrome,modal=yes,centerscreen", null );
}
// Menubar handling
function onHTMLContextMenu( target )
{
if ( theHTMLContextURL )
{
var v = target.getAttribute( "id" );
switch ( v )
{
case "html.context.open":
if ( IsMediaUrl( theHTMLContextURL ) )
{
URL.SetValue(theHTMLContextURL);
playCurrentUrl( true );
}
else
{
LaunchMainPaneURL( theHTMLContextURL );
}
break;
case "html.context.play":
URL.SetValue(theHTMLContextURL);
playCurrentUrl( true );
break;
case "html.context.add":
SBAddUrlToDatabase( theHTMLContextURL );
break;
case "html.context.playlist":
SBScanServiceTreeNewEntryEditable();
var success = thePlaylistReader.AutoLoad(theHTMLContextURL, "songbird", ConvertUrlToDisplayName( theHTMLContextURL ), "http", theHTMLContextURL, "", null);
SBScanServiceTreeNewEntryStart();
break;
}
theHTMLContextURL = null; // clear it because now we're done.
}
}
var theMediaScanIsOpen = new sbIDataRemote( "media_scan.open" );
function SBScanMedia( )
{
theMediaScanIsOpen.SetValue( true );
const nsIFilePicker = Components.interfaces.nsIFilePicker;
const CONTRACTID_FILE_PICKER = "@mozilla.org/filepicker;1";
var fp = Components.classes[CONTRACTID_FILE_PICKER].createInstance(nsIFilePicker);
var welcome = "Welcome";
var scan = "Scan";
try
{
welcome = theSongbirdStrings.getString("faceplate.welcome");
scan = theSongbirdStrings.getString("faceplate.scan");
} catch(e) {}
fp.init( window, welcome + "!\n\n" + scan, nsIFilePicker.modeGetFolder );
var res = fp.show();
if ( res == nsIFilePicker.returnOK )
{
var media_scan_data = new Object();
media_scan_data.URL = fp.file.path;
media_scan_data.retval = "";
// Open the non-modal dialog
SBOpenModalDialog( "chrome://rmp_demo/content/media_scan.xul", "media_scan", "chrome,modal=yes,centerscreen", media_scan_data );
}
theMediaScanIsOpen.SetValue( false );
}
function SBMabOpen()
{
var mab_data = new Object();
mab_data.retval = "";
// Open the modal dialog
SBOpenModalDialog( "chrome://rmp_demo/content/mab.xul", "Mozilla Amazon Browser", "chrome,modal=no", mab_data );
}
function SBNewPlaylist()
{
try
{
SBScanServiceTreeNewEntryEditable();
var query = new sbIDatabaseQuery();
query.SetDatabaseGUID( "songbird" );
var playlistmanager = new sbIPlaylistManager();
var aUUIDGenerator = Components.classes["@mozilla.org/uuid-generator;1"].createInstance(Components.interfaces.nsIUUIDGenerator);
var playlistguid = aUUIDGenerator.generateUUID();
var playlist = playlistmanager.CreatePlaylist( playlistguid, name, "Playlist", "user", query );
SBScanServiceTreeNewEntryStart();
}
catch ( err )
{
alert( "SBNewPlaylist - " + err );
}
}
function SBMiniplayerOpen()
{
// Open the window
window.open( "chrome://rmp_demo/content/miniplayer/miniplayer.xul", "", "chrome,modal=no,popup=yes" );
onExit();
}
function SBNewSmartPlaylist( guid, table )
{
SBScanServiceTreeNewEntryEditable(); // Do this right before you add to the servicelist?
// Make a magic data object to get passed to the dialog
var smart_playlist = new Object();
smart_playlist.retval = "";
smart_playlist.guid = guid;
smart_playlist.table = table
// Open the window
SBOpenModalDialog( "chrome://rmp_demo/content/smart_playlist.xul", "", "chrome,modal=yes,centerscreen", smart_playlist );
if ( smart_playlist.retval == "ok" )
{
SBScanServiceTreeNewEntryStart(); // And this once you know you really did?
}
}
function SBKoshiOpen()
{
// Make a magic data object to get passed to the dialog
var koshi_data = new Object();
koshi_data.retval = "";
// Open the window
SBOpenModalDialog( "chrome://rmp_demo/content/koshi_test.xul", "", "chrome,modal=yes,centerscreen", koshi_data );
}
function SBExtensionsManagerOpen()
{
const EMTYPE = "Extension:Manager";
var aOpenMode = 'extensions';
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var needToOpen = true;
var windowType = EMTYPE + "-" + aOpenMode;
var windows = wm.getEnumerator(windowType);
while (windows.hasMoreElements()) {
var theEM = windows.getNext().QueryInterface(Components.interfaces.nsIDOMWindowInternal);
if (theEM.document.documentElement.getAttribute("windowtype") == windowType) {
theEM.focus();
needToOpen = false;
break;
}
}
if (needToOpen) {
const EMURL = "chrome://mozapps/content/extensions/extensions.xul?type=" + aOpenMode;
const EMFEATURES = "chrome,dialog=no,resizable";
window.openDialog(EMURL, "", EMFEATURES);
}
}
function SBDOMInspectorOpen()
{
window.open("chrome://inspector/content/", "", "chrome,dialog=no,resizable");
}
function SBSubscribe( url, guid, table, readable_name )
{
// Make a magic data object to get passed to the dialog
var subscribe_data = new Object();
subscribe_data.retval = "";
subscribe_data.url = url;
subscribe_data.readable_name = readable_name;
// Open the window
SBScanServiceTreeNewEntryEditable();
SBOpenModalDialog( "chrome://rmp_demo/content/subscribe.xul", "", "chrome,modal=yes,centerscreen", subscribe_data );
if ( subscribe_data.retval == "ok" )
{
if ( guid && table )
{
const PlaylistManager = new Components.Constructor("@songbird.org/Songbird/PlaylistManager;1", "sbIPlaylistManager");
var aPlaylistManager = new PlaylistManager();
aPlaylistManager = aPlaylistManager.QueryInterface(Components.interfaces.sbIPlaylistManager);
var aDBQuery = new sbIDatabaseQuery();
aDBQuery.SetAsyncQuery(false);
aDBQuery.SetDatabaseGUID(guid);
aPlaylistManager.DeletePlaylist( table, aDBQuery );
}
SBScanServiceTreeNewEntryStart();
}
}
function About( )
{
// Make a magic data object to get passed to the dialog
var about_data = new Object();
about_data.retval = "";
// Open the modal dialog
SBOpenModalDialog( "chrome://rmp_demo/content/about.xul", "about", "chrome,modal=yes,centerscreen", about_data );
if ( about_data.retval == "ok" )
{
}
}
// Debugging Tool
function listProperties(obj, objName)
{
var columns = 3;
var count = 0;
var result = "";
for (var i in obj)
{
result += objName + "." + i + " = " + obj[i] + "\t\t\t";
count = ++count % columns;
if ( count == columns - 1 )
{
result += "\n";
}
}
alert(result);
}
var SBDropObserver =
{
getSupportedFlavours : function ()
{
var flavours = new FlavourSet();
flavours.appendFlavour("application/x-moz-file","nsIFile");
// flavours.appendFlavour("application/x-moz-url");
return flavours;
},
onDragOver: function ( evt, flavour, session )
{
},
onDrop: function ( evt, dropdata, session )
{
if ( dropdata.data != "" )
{
// if it has a path property
if ( dropdata.data.path )
{
theDropPath = dropdata.data.path;
theDropIsDir = dropdata.data.isDirectory();
setTimeout( SBDropped, 10 ); // Next frame
}
}
}
};
var theDropPath = "";
var theDropIsDir = false;
function SBDropped()
{
if ( IsMediaUrl( theDropPath ) )
{
// try to add it to the database.
SBAddUrlToDatabase( theDropPath );
// and then play it.
URL.SetValue(theDropPath);
playCurrentUrl( true );
}
else if ( theDropIsDir )
{
theMediaScanIsOpen.SetValue( true );
// otherwise, fire off the media scan page.
var media_scan_data = new Object();
media_scan_data.URL = theDropPath;
media_scan_data.retval = "";
// Open the non-modal dialog
SBOpenModalDialog( "chrome://rmp_demo/content/media_scan.xul", "media_scan", "chrome,modal=yes,centerscreen", media_scan_data );
theMediaScanIsOpen.SetValue( false );
}
}
function SBGetServiceFromUrl( url )
{
retval = url;
try
{
var theServiceTree = document.getElementById( "frame_service_tree" );
if ( theServiceTree )
{
// Find the columns.
var urlcolumn = theServiceTree.columns ? theServiceTree.columns["url"] : "url";
var labelcolumn = theServiceTree.columns ? theServiceTree.columns["frame_service_tree_label"] : "frame_service_tree_label";
for ( var i = 0; i < theServiceTree.view.rowCount; i++ )
{
// Get the text of the hidden tree cell, this contains the url.
var tree_url = theServiceTree.view.getCellText( i, urlcolumn );
var tree_label = theServiceTree.view.getCellText( i, labelcolumn );
if ( tree_url == url )
{
retval = tree_label;
break;
}
}
}
}
catch ( err )
{
alert( "SBGetServiceFromUrl - " + err )
}
return retval;
}
function SBGetServiceImageFromUrl( url )
{
retval = "";
try
{
var theServiceTree = document.getElementById( "frame_service_tree" );
if ( theServiceTree )
{
// Find the columns.
var urlcolumn = theServiceTree.columns ? theServiceTree.columns["url"] : "url";
var labelcolumn = theServiceTree.columns ? theServiceTree.columns["frame_service_tree_label"] : "frame_service_tree_label";
for ( var i = 0; i < theServiceTree.view.rowCount; i++ )
{
// Get the text of the hidden tree cell, this contains the url.
var tree_url = theServiceTree.view.getCellText( i, urlcolumn );
var tree_image = theServiceTree.view.getImageSrc( i, labelcolumn );
if ( tree_url == url )
{
retval = tree_image;
break;
}
}
}
}
catch ( err )
{
alert( "SBGetServiceImageFromUrl - " + err )
}
return retval;
}
function SBGetUrlFromService( service )
{
retval = service;
try
{
var theServiceTree = document.getElementById( "frame_service_tree" );
if ( theServiceTree )
{
// Find the columns.
var urlcolumn = theServiceTree.columns ? theServiceTree.columns["url"] : "url";
var labelcolumn = theServiceTree.columns ? theServiceTree.columns["frame_service_tree_label"] : "frame_service_tree_label";
for ( var i = 0; i < theServiceTree.view.rowCount; i++ )
{
// Get the text of the hidden tree cell, this contains the url.
var tree_url = theServiceTree.view.getCellText( i, urlcolumn );
var tree_label = theServiceTree.view.getCellText( i, labelcolumn );
if ( tree_label == service )
{
retval = tree_url;
break;
}
}
}
}
catch ( err )
{
alert( "SBGetUrlFromService - " + err )
}
return retval;
}
function SBTabcompleteService( service )
{
retval = service;
var service_lc = service.toLowerCase();
try
{
var theServiceTree = document.getElementById( "frame_service_tree" );
if ( theServiceTree )
{
// Find the columns.
var urlcolumn = theServiceTree.columns ? theServiceTree.columns["url"] : "url";
var labelcolumn = theServiceTree.columns ? theServiceTree.columns["frame_service_tree_label"] : "frame_service_tree_label";
var found_one = false;
for ( var i = 0; i < theServiceTree.view.rowCount; i++ )
{
// Get the text of the hidden tree cell, this contains the url.
var tree_label = theServiceTree.view.getCellText( i, labelcolumn );
var label_lc = tree_label.toLowerCase();
// If we are the beginning of the label string
if ( label_lc.indexOf( service_lc ) == 0 )
{
if ( found_one )
{
retval = service; // only find ONE!
break;
}
else
{
found_one = true; // only find ONE!
retval = tree_label;
}
}
}
}
}
catch ( err )
{
alert( "SBTabcompleteService - " + err )
}
return retval;
}
// Assume there's just one?
var theDownloadContext = new sbIDataRemote( "download.context" );
var theDownloadTable = new sbIDataRemote( "download.table" );
var theDownloadExists = new sbIDataRemote( "browser.hasdownload" );
/*
var theDownloadListener =
{
m_queryObj: null,
m_libraryObj: null,
CreateQueryObj: function()
{
this.m_queryObj = new sbIDatabaseQuery();
this.m_queryObj.SetAsyncQuery(true);
this.m_queryObj.SetDatabaseGUID("songbird");
},
CreateLibraryObj: function()
{
if(this.m_libraryObj == null)
{
const MediaLibrary = new Components.Constructor("@songbird.org/Songbird/MediaLibrary;1", "sbIMediaLibrary");
this.m_libraryObj = (new MediaLibrary()).QueryInterface(Components.interfaces.sbIMediaLibrary);
if(this.m_queryObj == null)
this.CreateQueryObj();
this.m_libraryObj.SetQueryObject(this.m_queryObj);
}
},
QueryInterface : function(aIID)
{
if (!aIID.equals(Components.interfaces.sbIDeviceBaseCallback) &&
!aIID.equals(Components.interfaces.nsISupports))
{
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
onTransferStart: function(sourceURL, destinationURL)
{
},
onTransferComplete: function(sourceURL, destinationURL, transferStatus)
{
if(transferStatus == 1)
{
this.CreateLibraryObj();
var aKeys = ["title"];
var aValues = [];
var aLocalFile = (Components.classes["@mozilla.org/file/local;1"]).createInstance(Components.interfaces.nsILocalFile);
aLocalFile.initWithPath(destinationURL);
aValues.push(aLocalFile.leafName);
this.m_libraryObj.AddMedia(destinationURL, aKeys.length, aKeys, aValues.length, aValues, false, false);
}
}
};
*/
function onBrowserTransfer(guid, table, strFilterColumn, nFilterValueCount, aFilterValues)
{
try
{
theWebPlaylistQuery = null;
aDeviceManager = Components.classes["@songbird.org/Songbird/DeviceManager;1"].createInstance(Components.interfaces.sbIDeviceManager);
if (aDeviceManager)
{
aDownloadDevice = aDeviceManager.GetDevice('Songbird Download Device');
if (aDownloadDevice)
{
// Make a magic data object to get passed to the dialog
var download_data = new Object();
download_data.retval = "";
download_data.value = SBDataGetValue( "download.folder" );
if ( ( SBDataGetIntValue( "download.always" ) == 1 ) && ( download_data.value.length > 0 ) )
{
download_data.retval = "ok";
}
else
{
// Open the window
SBOpenModalDialog( "chrome://rmp_demo/content/download.xul", "", "chrome,modal=yes,centerscreen", download_data );
}
// Pick download destination
if ( ( download_data.retval == "ok" ) && ( download_data.value.length > 0 ) )
{
var downloadTable = {};
// Passing empty string for device name as download device has just one device
// Prepare table for download & get the name for newly prepared download table
//aDownloadDevice.AddCallback(theDownloadListener);
aDownloadDevice.AutoDownloadTable('', guid, table, strFilterColumn, nFilterValueCount, aFilterValues, '', download_data.value, downloadTable);
// Record the current download table
theDownloadContext.SetValue( aDownloadDevice.GetContext('') )
theDownloadTable.SetValue( downloadTable.value );
theDownloadExists.SetValue( true );
// Register the guid and table with the playlist source to always show special download commands.
SBDownloadCommands.m_Device = aDownloadDevice;
var source = new sbIPlaylistsource();
source.RegisterPlaylistCommands( aDownloadDevice.GetContext(''), downloadTable.value, "download", SBDownloadCommands );
}
}
}
}
catch ( err )
{
alert( err );
}
}
var SBDownloadCommands =
{
DEVICE_IDLE : 0,
DEVICE_BUSY : 1,
DEVICE_DOWNLOADING : 2,
DEVICE_UPLOADING : 3,
DEVICE_DOWNLOAD_PAUSED : 4,
DEVICE_UPLOAD_PAUSED : 5,
DEVICE_DELETING : 6,
m_Playlist: null,
m_Device: null,
m_Ids: new Array
(
"library_cmd_play",
"library_cmd_remove",
"library_cmd_pause"
),
m_Names: new Array
(
"&command.play",
"&command.remove",
"&command.pause"
),
m_Tooltips: new Array
(
"&command.tooltip.play",
"&command.tooltip.remove",
"&command.tooltip.pause"
),
GetNumCommands: function()
{
if (
( this.m_Tooltips.length != this.m_Ids.length ) ||
( this.m_Names.length != this.m_Ids.length ) ||
( this.m_Tooltips.length != this.m_Names.length )
)
{
alert( "PlaylistCommands - Array lengths do not match!" );
return 0;
}
return this.m_Ids.length;
},
GetCommandId: function( index )
{
if ( index == 2 )
{
if ( this.m_Device )
{
if ( this.m_Device.GetDeviceState('') == this.DEVICE_DOWNLOAD_PAUSED )
{
this.m_Ids[ index ] = "library_cmd_resume";
}
else
{
this.m_Ids[ index ] = "library_cmd_pause";
}
}
}
if ( index >= this.m_Ids.length )
{
return "";
}
return this.m_Ids[ index ];
},
GetCommandText: function( index )
{
if ( index == 2 )
{
if ( this.m_Device )
{
if ( this.m_Device.GetDeviceState('') == this.DEVICE_DOWNLOAD_PAUSED )
{
this.m_Names[ index ] = "&command.resume";
}
else
{
this.m_Names[ index ] = "&command.pause";
}
}
}
if ( index >= this.m_Names.length )
{
return "";
}
return this.m_Names[ index ];
},
GetCommandToolTipText: function( index )
{
if ( index == 2 )
{
if ( this.m_Device )
{
if ( this.m_Device.GetDeviceState('') == this.DEVICE_DOWNLOAD_PAUSED )
{
this.m_Tooltips[ index ] = "&command.tooltip.resume";
}
else
{
this.m_Tooltips[ index ] = "&command.tooltip.pause";
}
}
}
if ( index >= this.m_Tooltips.length )
{
return "";
}
return this.m_Tooltips[ index ];
},
GetCommandEnabled: function( index )
{
var retval = false;
if ( this.m_Device )
{
switch( index )
{
case 0:
case 1:
retval = true;
break;
case 2:
retval = ( this.m_Device.GetDeviceState('') == this.DEVICE_DOWNLOADING ) || ( this.m_Device.GetDeviceState('') == this.DEVICE_DOWNLOAD_PAUSED )
break;
}
}
return retval;
},
OnCommand: function( event )
{
if ( this.m_Device && event.target && event.target.id )
{
// Was it from the toolbarbutton?
var tbb = ( event.target.tagName == "toolbarbutton" || event.target.tagName == "xul:toolbarbutton" );
switch( event.target.id )
{
case "library_cmd_play":
if ( this.m_Playlist.tree.currentIndex != -1 )
{
// Repurpose the command to act as if a doubleclick
this.m_Playlist.sendPlayEvent();
}
break;
case "library_cmd_remove":
if ( this.m_Playlist.tree.currentIndex != -1 )
{
// remove the currently select tracks
this.m_Playlist.removeTracks();
}
break;
case "library_cmd_pause":
case "library_cmd_resume":
if ( this.m_Device.GetDeviceState('') == this.DEVICE_DOWNLOADING )
{
this.m_Device.SuspendTransfer('');
}
else if ( this.m_Device.GetDeviceState('') == this.DEVICE_DOWNLOAD_PAUSED )
{
this.m_Device.ResumeTransfer('');
}
// Since we changed state, update the command buttons.
this.m_Playlist.refreshCommands();
break;
}
event.stopPropagation();
}
},
// The object registered with the sbIPlaylistSource interface acts
// as a template for instances bound to specific playlist elements
Duplicate: function()
{
var obj = {};
for ( var i in this )
{
obj[ i ] = this[ i ];
}
return obj;
},
SetPlaylist: function( playlist )
{
this.m_Playlist = playlist;
},
QueryInterface : function(aIID)
{
if (!aIID.equals(Components.interfaces.sbIPlaylistCommands) &&
!aIID.equals(Components.interfaces.nsISupportsWeakReference) &&
!aIID.equals(Components.interfaces.nsISupports))
{
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
}
}
// Register the download commands at startup if we know what the download table is.
aDeviceManager = Components.classes["@songbird.org/Songbird/DeviceManager;1"].createInstance(Components.interfaces.sbIDeviceManager);
if (aDeviceManager)
{
aDownloadDevice = aDeviceManager.GetDevice('Songbird Download Device');
if (aDownloadDevice)
{
SBDownloadCommands.m_Device = aDownloadDevice;
var guid = aDownloadDevice.GetContext('');
var table = "download"; // aDownloadDevice.GetTransferTableName('');
var source = new sbIPlaylistsource();
try
{
source.RegisterPlaylistCommands( guid, table, "download", SBDownloadCommands );
}
catch ( err )
{
alert( "source.RegisterPlaylistCommands( " + guid+ ", " + table+ " );\r\n" + err )
}
}
}
// END
}
catch ( err )
{
alert( err );
}
// alert( "success!" );